import 'dart:convert';

import 'package:shared_preferences/shared_preferences.dart';
import 'package:sonora/models/sj_broad_caster_data.dart';
import 'package:sonora/models/sj_broad_caster_response_data.dart';
import 'package:sonora/models/sj_config_data.dart';
import 'package:sonora/models/sj_login_response_data.dart';
import 'package:sonora/models/sj_medal_data.dart';
import 'package:sonora/models/sj_media_data.dart';
import 'package:sonora/models/sj_strategy_data.dart';
import 'package:sonora/models/sj_works_model.dart';

class SjStorageUtils {
  static const String _appLaunchKey = 'appLaunchKey';
  static const String _appConfigKey = 'appConfig';
  static const String _loginDataKey = 'loginDataKey';
  static const String _broadCasterResponseDataKey =
      'broadCasterResponseDataKey';
  static const String _worksDataKey = 'worksDataKey';
  static const String _logoutKey = 'logoutKey';
  static const String _strategyKey = 'strategyKey';
  static const String _mediaKey = 'mediaKey';
  static const String _wallSearchKey = 'wallSearchKey';
  static const String _medalListKey = 'medalListKey';
  static const String _medalPageFirstKey = 'medalPageFirstKey';
  static const String _autoTranslateKey = 'autoTranslateKey';
  static const String _userDetailKey = 'userDetailKey';
    static const String _userFirstCommnetKey = 'userFirstCommnetKey';
  static const String _userFirstPostKey = 'userFirstPostKey';

    static Future<bool> getUserFirstCommnetKey() async {
    final prefs = await SharedPreferences.getInstance();
    final SjLoginData? loginData = await SjStorageUtils.getLoginInfo();
    String? userId = loginData?.userInfo?.userId;
    bool? firstLaunch = prefs.getBool('${userId ?? ''}_$_userFirstCommnetKey');
    if (firstLaunch == null) {
      prefs.setBool('${userId ?? ''}_$_userFirstCommnetKey', false);
      return true;
    }
    return firstLaunch;
  }

  static Future<bool> getUserFirstPostKey() async {
    final prefs = await SharedPreferences.getInstance();
    final SjLoginData? loginData = await SjStorageUtils.getLoginInfo();
    String? userId = loginData?.userInfo?.userId;
    bool? firstLaunch = prefs.getBool('${userId ?? ''}_$_userFirstPostKey');
    if (firstLaunch == null) {
      prefs.setBool('${userId ?? ''}_$_userFirstPostKey', false);
      return true;
    }
    return firstLaunch;
  }

  static Future<void> saveAppFirstLaunch() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setBool(_appLaunchKey, true);
  }

  static Future<bool> getAppFirstLaunch() async {
    final prefs = await SharedPreferences.getInstance();
    bool? firstLaunch = prefs.getBool(_appLaunchKey);
    return firstLaunch == null;
  }

  static Future<void> saveLoginInfo(Map<String, dynamic>? loginData) async {
    if (loginData == null) return;
    final prefs = await SharedPreferences.getInstance();
    String jsonString = jsonEncode(loginData);
    await prefs.setString(_loginDataKey, jsonString);
    await prefs.setBool(_logoutKey, false);
  }

  static Future<SjLoginData?> getLoginInfo() async {
    final prefs = await SharedPreferences.getInstance();
    String? jsonString = prefs.getString(_loginDataKey);
    if (jsonString != null) {
      Map<String, dynamic> jsonMap = jsonDecode(jsonString);
      return SjLoginData.fromJson(jsonMap);
    }
    return null;
  }

  static Future<void> saveUserDetail(Map<String, dynamic>? userDetail) async {
    if (userDetail == null) return;
    final prefs = await SharedPreferences.getInstance();
    String jsonString = jsonEncode(userDetail);
    final SjLoginData? loginData = await SjStorageUtils.getLoginInfo();
    String? userId = loginData?.userInfo?.userId;
    await prefs.setString('${userId ?? ''}_$_userDetailKey', jsonString);
  }

  static Future<SjUserDetailData?> getUserDetail() async {
    final prefs = await SharedPreferences.getInstance();
    final SjLoginData? loginData = await SjStorageUtils.getLoginInfo();
    String? userId = loginData?.userInfo?.userId;
    String? jsonString = prefs.getString('${userId ?? ''}_$_userDetailKey');
    if (jsonString != null) {
      Map<String, dynamic> jsonMap = jsonDecode(jsonString);
      return SjUserDetailData.fromJson(jsonMap);
    }
    return null;
  }

  static Future<void> saveStrategyData(Map<String, dynamic>? data) async {
    if (data == null) return;
    final prefs = await SharedPreferences.getInstance();
    String jsonString = jsonEncode(data);
    await prefs.setString(_strategyKey, jsonString);
  }

  static Future<SjStrategyData?> getStrategy() async {
    final prefs = await SharedPreferences.getInstance();
    String? jsonString = prefs.getString(_strategyKey);
    if (jsonString != null) {
      Map<String, dynamic> jsonMap = jsonDecode(jsonString);
      return SjStrategyData.fromJson(jsonMap);
    }
    return null;
  }

  static Future<bool?> getAccountLogout() async {
    final prefs = await SharedPreferences.getInstance();
    bool? firstLaunch = prefs.getBool(_logoutKey);
    return firstLaunch;
  }

  static Future<void> clearLoginInfo() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove(_loginDataKey);
    await prefs.setBool(_logoutKey, true);
  }

  static Future<void> saveAppConfig(SjConfigData? configData) async {
    if (configData == null) return;
    final prefs = await SharedPreferences.getInstance();
    String jsonString = jsonEncode(configData.toJson());
    await prefs.setString(_appConfigKey, jsonString);
  }

  static Future<SjConfigData?> getAppConfig() async {
    final prefs = await SharedPreferences.getInstance();
    String? jsonString = prefs.getString(_appConfigKey);
    if (jsonString != null) {
      Map<String, dynamic> jsonMap = jsonDecode(jsonString);
      return SjConfigData.fromJson(jsonMap);
    }
    return null;
  }

  static Future<void> saveBroadCasterResponseData(
      SjBroadCasterResponseData? data) async {
    if (data == null) return;
    final prefs = await SharedPreferences.getInstance();
    String jsonString = jsonEncode(data.toJson());
    await prefs.setString(_broadCasterResponseDataKey, jsonString);
  }

  static Future<SjBroadCasterResponseData?> getBroadCasterResponseData() async {
    final prefs = await SharedPreferences.getInstance();
    String? jsonString = prefs.getString(_broadCasterResponseDataKey);
    if (jsonString != null) {
      Map<String, dynamic> jsonMap = jsonDecode(jsonString);
      return SjBroadCasterResponseData.fromJson(jsonMap);
    }
    return null;
  }

  static Future<void> saveWorksList(List<SjWorksModel>? data) async {
    if (data == null) return;
    final prefs = await SharedPreferences.getInstance();
    List<String> jsonStringList =
        data.map((e) => jsonEncode(e.toJson())).toList();
    final SjLoginData? loginData = await SjStorageUtils.getLoginInfo();
    String? userId = loginData?.userInfo?.userId;
    await prefs.setStringList('${userId ?? ''}_$_worksDataKey', jsonStringList);
  }

  static Future<List<SjWorksModel>?> getWorksList() async {
    final SjLoginData? loginData = await SjStorageUtils.getLoginInfo();
    String? userId = loginData?.userInfo?.userId;
    final prefs = await SharedPreferences.getInstance();
    List<String>? jsonStringList =
        prefs.getStringList('${userId ?? ''}_$_worksDataKey');
    if (jsonStringList == null) return null;
    return jsonStringList.map((e) {
      Map<String, dynamic> jsonMap = jsonDecode(e);
      return SjWorksModel.fromJson(jsonMap);
    }).toList();
  }

  static Future<void> insertWork(SjWorksModel? data) async {
    if (data == null) return;
    List<SjWorksModel>? list = await getWorksList();
    list ??= [];
    if (list.isEmpty) {
      list.add(data);
    } else {
      final tempList = list.where((element) => element.worksId == data.worksId).toList();
      if (tempList.isEmpty) {
        list.insert(0, data);
      } else {
        SjWorksModel matchData = tempList.first;
        SjWorksModel newData = 
            SjWorksModel.fromJson(data.toJson());
        list.replaceRange(list.indexOf(matchData), list.indexOf(matchData) + 1, [newData]);
      }
    }
    saveWorksList(list);
  }

  static Future<void> updateWorksList(List<SjWorksModel>? list) async {
    if (list == null || list.isEmpty) {
      return;
    }
    for (var element in list) {
      await insertWork(element);
    }
  }

  static Future<SjWorksModel?> getWorks(int? worksId) async {
    if (worksId == null) return null;
    List<SjWorksModel>? list = await getWorksList();
    if (list == null || list.isEmpty) return null;
    final tempList = list.where((element) => element.worksId == worksId);
    if (tempList.isEmpty) return null;
    return tempList.first;
  }

  static Future<List<SjWorksModel>?> getWorksByUserId(String? userId) async {
    if (userId == null) return null;
    List<SjWorksModel>? list = await getWorksList();
    if (list == null || list.isEmpty) return null;
    final tempList = list.where((element) => element.userId == userId).toList();
    return tempList;
  }

  static Future<bool> deleteWorks(String? worksId) async {
    if (worksId == null) return false;
    List<SjWorksModel>? list = await getWorksList();
    if (list == null || list.isEmpty) return false;
    final tempList = list.where((element) => element.worksId == worksId);
    if (tempList.isEmpty) return false;
    list.removeAt(list.indexOf(tempList.first));
    saveWorksList(list);
    return true;
  }

  static Future<void> clearWorksList() async {
    final SjLoginData? loginData = await SjStorageUtils.getLoginInfo();
    String? userId = loginData?.userInfo?.userId;
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove('${userId ?? ''}_$_worksDataKey');
  }

  static Future<void> saveMedialList(List<SjMediaData>? data) async {
    if (data == null) return;
    final prefs = await SharedPreferences.getInstance();
    List<String> jsonStringList =
        data.map((e) => jsonEncode(e.toJson())).toList();
    final SjLoginData? loginData = await SjStorageUtils.getLoginInfo();
    String? userId = loginData?.userInfo?.userId;
    await prefs.setStringList('${userId ?? ''}_$_mediaKey', jsonStringList);
  }

  static Future<List<SjMediaData>?> getMediaList() async {
    final SjLoginData? loginData = await SjStorageUtils.getLoginInfo();
    String? userId = loginData?.userInfo?.userId;
    final prefs = await SharedPreferences.getInstance();
    List<String>? jsonStringList =
        prefs.getStringList('${userId ?? ''}_$_mediaKey');
    if (jsonStringList == null) return null;
    return jsonStringList.map((e) {
      Map<String, dynamic> jsonMap = jsonDecode(e);
      return SjMediaData.fromJson(jsonMap);
    }).toList();
  }

  static Future<void> saveWallSearch(List<SjBroadCasterData>? list) async {
    if (list == null) return;
    final prefs = await SharedPreferences.getInstance();
    List<String> jsonStringList =
        list.map((e) => jsonEncode(e.toJson())).toList();
    await prefs.setStringList(_wallSearchKey, jsonStringList);
  }

  static Future<List<SjBroadCasterData>?> getWallSearchList() async {
    final prefs = await SharedPreferences.getInstance();
    List<String>? jsonStringList =
        prefs.getStringList(_wallSearchKey);
    if (jsonStringList == null) return null;
    return jsonStringList.map((e) {
      Map<String, dynamic> jsonMap = jsonDecode(e);
      return SjBroadCasterData.fromJson(jsonMap);
    }).toList();
  }

  static Future<void> saveMedalList(List<SjMedalData>? data) async {
    if (data == null) return;
    final prefs = await SharedPreferences.getInstance();
    List<String> jsonStringList =
        data.map((e) => jsonEncode(e.toJson())).toList();
    final SjLoginData? loginData = await SjStorageUtils.getLoginInfo();
    String? userId = loginData?.userInfo?.userId;
    await prefs.setStringList('${userId ?? ''}_$_medalListKey', jsonStringList);
  }

  static Future<List<SjMedalData>?> getMedalList() async {
    final SjLoginData? loginData = await SjStorageUtils.getLoginInfo();
    String? userId = loginData?.userInfo?.userId;
    final prefs = await SharedPreferences.getInstance();
    List<String>? jsonStringList =
        prefs.getStringList('${userId ?? ''}_$_medalListKey');
    if (jsonStringList == null) return null;
    return jsonStringList.map((e) {
      Map<String, dynamic> jsonMap = jsonDecode(e);
      return SjMedalData.fromJson(jsonMap);
    }).toList();
  }

  static Future<bool?> getMedalPageNotFirst() async {
    final SjLoginData? loginData = await SjStorageUtils.getLoginInfo();
    String? userId = loginData?.userInfo?.userId;
    final prefs = await SharedPreferences.getInstance();
    bool? value =
        prefs.getBool('${userId ?? ''}_$_medalPageFirstKey');
    if (value == null) {
      prefs.setBool('${userId ?? ''}_$_medalPageFirstKey', true);
    }
    return value;
  }

  static Future<void> saveAutoTranslate(bool autoTranslate) async {
    final prefs = await SharedPreferences.getInstance();
    final SjLoginData? loginData = await SjStorageUtils.getLoginInfo();
    String? userId = loginData?.userInfo?.userId;
    await prefs.setBool('${userId ?? ''}_$_autoTranslateKey', autoTranslate);
  }

  static Future<bool?> getAutoTranslate() async {
    final SjLoginData? loginData = await SjStorageUtils.getLoginInfo();
    String? userId = loginData?.userInfo?.userId;
    final prefs = await SharedPreferences.getInstance();
    bool? value =
        prefs.getBool('${userId ?? ''}_$_autoTranslateKey');
    return value;
  }
}
